/**
 * 
 */
package weibo4j.crawler;

import java.sql.SQLException;
import java.util.concurrent.LinkedBlockingQueue;


/**
 * @author longrui
 * 
 */

public class QueueBase {
	protected QueueBuffer queueInDB;
	protected LinkedBlockingQueue<QueueRecord> queueInMem;
	protected int maxLengthInMem;

	public QueueBase(QueueBuffer qb, int qmLength) throws Exception {
		this.queueInDB = qb;
		this.maxLengthInMem = qmLength;
		queueInMem = new LinkedBlockingQueue<QueueRecord>();

		if (getLength() > 0)
			loadDBDataIntoMem();
	}

	public LinkedBlockingQueue<QueueRecord> getQueueInMem() {
		return queueInMem;
	}

	public int getType() {
		return queueInDB.type;
	}

	public synchronized long getLength() throws Exception {
		//System.out.println("queueInDB is null? :" + queueInDB == null);
		//System.out.println("queueInMem is null? :" + queueInMem == null);
		return queueInDB.getLength() + queueInMem.size();
	}

	private synchronized boolean exist(QueueRecord rec) throws SQLException {
		boolean res = queueInDB.contains(rec) || queueInMem.contains(rec);
		return res;
	}

	public synchronized boolean add(QueueRecord rec) throws Exception {
		// System.err.println("add to queue's value: " + value);
		if (rec == null)
			return false;
		if (!exist(rec)) {
			if (queueInMem.size() < maxLengthInMem) {
				queueInMem.add(rec);
			} else {
				queueInDB.add(rec);
			}
			return true;
		}
		return true;
	}

	public synchronized boolean saveMemDataIntoDB() throws Exception {
		int queueLength = 0;
		int count = 0;
		queueLength = queueInMem.size();
		QueueRecord rec = null;
		count = 0;
		while ((rec = queueInMem.poll()) != null) {
			if (queueInDB.add(rec)) {
				count++;
			}
		}
		return count == queueLength;
	}

	public synchronized void loadDBDataIntoMem() throws SQLException {
		int count = 0;
		QueueRecord rec = null;
		while ((rec = queueInDB.poll()) != null && count < maxLengthInMem) {
			if (queueInMem.add(rec)) {
				count++;
			}
		}
		System.err.println(getType() + " have loaded rec is: " + count);
	}

	public void remove(QueueRecord rec) throws SQLException {
		if (rec == null)
			return;
		queueInMem.remove(rec);
		queueInDB.remove(rec);
	}

	public synchronized QueueRecord poll() throws SQLException {
		if (queueInMem.size() == 0)
			return null;

		QueueRecord firstValue = queueInMem.peek();
		QueueRecord rec = queueInDB.peek();
		if (rec != null) {
			queueInMem.add(rec);
			queueInDB.remove(rec);
		}
		queueInMem.poll();
		return firstValue;
	}

	public synchronized QueueRecord roll() throws Exception {
		if (queueInMem.size() == 0)
			return null;

		QueueRecord firstValue = queueInMem.peek();
		QueueRecord head = queueInDB.peek();
		if (head != null) {
			queueInMem.add(head);
			queueInDB.remove(head);
		}

		if (queueInMem.size() <= maxLengthInMem - 1)
			queueInMem.add(firstValue);
		else
			queueInDB.add(firstValue);
		queueInMem.poll();

		return firstValue;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
